/**
 * Copyright (C), 2015-2020, XXX有限公司
 * FileName: ProcessYNFJ
 * Author:   ThinkPad
 * Date:     2020/6/24 17:01
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.jt.www.queue.process;

import com.jt.www.enums.issue.IssueEnum;
import com.jt.www.enums.issue.PolicyInterfaceEnum;
import com.jt.www.model.issue.entity.IssuePolicyLogEntity;
import com.jt.www.model.issue.entity.IssueRecordEntity;
import com.jt.www.util.DateUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.util.StringUtil;

import java.util.Random;

/**
 * @author xq.wu
 * @Description 云南非九（校方综合防范保障保险、教职员工校方责任保险、云南省校方责任保险、校园食品安全责任保险）
 * @create 2020/6/24
 * @since 1.0.0
 */
@Service
public class ProcessYNFJ extends ElecPolicyProcess implements InitializingBean {

    public static final Logger log = LoggerFactory.getLogger(ProcessYNFJ.class);

    /**
     * 初始化工厂
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        IssuePolicyIfCodeFactory.register(PolicyInterfaceEnum.CODE_6.getIfCode(), this);
    }

    @Override
    public Boolean process(Element rootElement, String ifCode) {
        // 解析xml，封装数据
        Element reqPacket = getReqPacket(rootElement);
        Element respPacket = getRespPacket(rootElement);

        String policyType = reqPacket.element("body").element("apply").element("policyType").getStringValue();

        String proCode = IssueEnum.getProCodeByIfCode(ifCode.concat(policyType));

        String companyCode = reqPacket.element("head").element("userId").getStringValue();
        String currentTime = DateUtils.getCurrentTime();
        // 投保单号
        String tbNo = rootElement.element("ApplicationFormCode").getStringValue();
        // 保单号
        String policyNo = rootElement.element("PolicyNo").getStringValue();
        // 入库
        // 入库之前首先判断 是否已经入库  根据投保单号判断
        if (judgingStorage(tbNo)) {
            return true;
        }
        IssueRecordEntity issueRecordEntity = new IssueRecordEntity();
        issueRecordEntity.setApplicationFormCode(tbNo);
        issueRecordEntity.setPolicyNo(policyNo);
        issueRecordEntity.setCompanyCode(companyCode);
        issueRecordEntity.setProCode(proCode);
        issueRecordEntity.setReqPacket(reqPacket.asXML());
        issueRecordEntity.setResPacket(respPacket.asXML());
        issueRecordEntity.setSendStatus("1");
        String status = respPacket.element("Head").element("ResponseCode").getStringValue();
        if ("0".equals(status)) {
            status = "2";
        } else {
            status = "3";
        }
        // 数据中心返回 的投保单状态
        issueRecordEntity.setStatus(status);
        issueRecordEntity.setCreateTime(currentTime);
        issueRecordEntity.setUpdateTime(currentTime);
        issueRecordEntity.setIfCode(ifCode);
        issueRecordEntityMapper.insert(issueRecordEntity);
        if ("3".equals(status)) {
            // 出单失败，消息直接消费完成，在入库的逻辑后边。
            return true;
        }
        // 消费:从响应体中解析出 url，去调用数据中心的接口，下载电子保单
        IssuePolicyLogEntity issuePolicyLogEntity = new IssuePolicyLogEntity();
        String consumeStatus = "1";
        issuePolicyLogEntity.setApplicationFormCode(tbNo);
        issuePolicyLogEntity.setPolicyNo(policyNo);
        issuePolicyLogEntity.setType("1");
        issuePolicyLogEntity.setStatus(consumeStatus);
        issuePolicyLogEntity.setCreateTime(currentTime);
        issuePolicyLogEntity.setUpdateTime(currentTime);
        issuePolicyLogEntity.setProCode(proCode);
        String url = respPacket.element("Body").element("Apply").element("PolicyImage").getStringValue();
        // 拼装下载报文
        Document doc = DocumentHelper.createDocument();
        Element info = doc.addElement("Body");
        info.addElement("url").addText(url);
        issuePolicyLogEntity.setParam(info.asXML());
        issuePolicyLogEntity.setIfCode(ifCode);
        issuePolicyLogEntity.setTimes(1);
        issuePolicyLogEntityMapper.insert(issuePolicyLogEntity);
        // 只要消息进入消费记录的库，就认为消费成功，修改消息记录表状态,具体有没有成功 记录在消费记录表，有定时任务。
        issueRecordEntity.setSendStatus("2");
        issueRecordEntityMapper.updateByPrimaryKeySelective(issueRecordEntity);
        //调用接口,请求数据交换中心，下载电子保单
        Boolean flag = false;
        try {
            // 请求下载保单，成功更新
            log.info(DateUtils.getCurrentTime() + "云南非九投保单号是 " + tbNo + " 下载保单开始，入参" + info.asXML());
            String seqNo = Long.toString(Math.abs(new Random().nextLong()));
            ResponseEntity<String> responseEntity = dexClient.text("edu", "20190516016", "1.0", seqNo, info.asXML());
            consumeStatus = "2";
            String ebody = responseEntity.getBody();
            log.info(DateUtils.getCurrentTime() + "云南非九投保单号是 " + tbNo + " 下载保单结束，回参" + ebody);
            doc = DocumentHelper.parseText(ebody);
            Element ebodyElement = doc.getRootElement();
            Element data = ebodyElement.element("data");
            if (data == null) {
                log.error("云南非九请求下载电子保单失败");
                consumeStatus = "3";
            } else {
                String fileId = data.getStringValue();
                issuePolicyLogEntity.setStatus(consumeStatus);
                // 下载成功，更新数据库，绑定资源
                log.info("云南非九 下载消息 fileId ：{}", fileId);
                bindingResources(tbNo, fileId, issuePolicyLogEntity);
                sendEmail(tbNo, "021");
            }
            // todo 下载电子发票 7-15 10:45
            IssuePolicyLogEntity t = new IssuePolicyLogEntity();
            consumeStatus = "1";
            t.setApplicationFormCode(tbNo);
            t.setPolicyNo(policyNo);
            t.setType("3");
            t.setStatus(consumeStatus);
            t.setCreateTime(currentTime);
            t.setUpdateTime(currentTime);
            t.setProCode(proCode);
            doc = DocumentHelper.createDocument();

            // 组装电子发票的报文
            String serialNo = respPacket.element("Head").element("SeqNo").getStringValue();
            String userId = respPacket.element("Head").element("UserId").getStringValue();
            String telephone = reqPacket.element("body").element("apply").element("policyHolder").element("telephone").getStringValue();
            String conEmail = reqPacket.element("body").element("apply").element("policyHolder").element("conEmail").getStringValue();
            String invoiceName = rootElement.element("invoiceName").getStringValue();
            String organizationCode = rootElement.element("organizationCode").getStringValue();
            String invoiceBank = rootElement.element("invoiceBank").getStringValue();
            String invoiceAddress = rootElement.element("invoiceBank").getStringValue();
            info = doc.addElement("FcyBasicLiabilityApply");
            doc.setRootElement(info);
            Element Head = info.addElement("head");
            Head.addElement("userId").addText(userId);
            Head.addElement("commandId").addText("ERA0005");
            Head.addElement("seqNo").addText(serialNo);
            Element Body = info.addElement("body");
            Element apply = Body.addElement("apply");
            apply.addElement("applyId").addText(tbNo);
            apply.addElement("policyNo").addText(policyNo);
            apply.addElement("phoneNumber").addText(telephone);// 电话
            apply.addElement("email").addText(conEmail);// 邮箱
            apply.addElement("organizationCode").addText(organizationCode);
            apply.addElement("invoiceName").addText(invoiceName);
            apply.addElement("invoiceBank").addText(invoiceBank);
            apply.addElement("invoiceAddress").addText(invoiceAddress);
            t.setParam(info.asXML());
            t.setTimes(0);
            issuePolicyLogEntity.setIfCode(ifCode);
            // 电子发票的消费记录入库
            issuePolicyLogEntityMapper.insert(t);

            // 调接口  生成发票
            log.info(DateUtils.getCurrentTime() + "云南非九投保单号是 " + tbNo + " 生成发票开始，入参" + info.asXML());
            seqNo = Long.toString(Math.abs(new Random().nextLong()));
            responseEntity = dexClient.text("edu", "20190516026", "1.0", seqNo, info.asXML());
            consumeStatus = "6";
            ebody = responseEntity.getBody();
            log.info(DateUtils.getCurrentTime() + "云南非九投保单号是 " + tbNo + " 生成发票结束，回参" + ebody);
            doc = DocumentHelper.parseText(ebody);
            ebodyElement = doc.getRootElement();
            // 根据code 0000  判断 。也可以根据返回值data判断  成功有数据，失败为null
            Element body = ebodyElement.element("body");
            Element head = ebodyElement.element("head");
            if (body != null) {// 说明请求成功  返回发票url
                url = body.element("url").getStringValue();
                String msg = head.element("msg").getStringValue();
                if (StringUtil.isEmpty(url)) {
                    log.error("云南非九请求生成电子发票失败");
                    consumeStatus = "7";
                    t.setStatus(consumeStatus);
                    t.setResponseMsg(msg);
                    // 生成电子发票失败，更新数据库，
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                } else {
                    // 组装下载电子发票的报文
                    doc = DocumentHelper.createDocument();
                    info = doc.addElement("Body");
                    Body = info.addElement("url");
                    Body.addText(url);
                    t.setDownParam(info.asXML());
                    t.setStatus(consumeStatus);
                    // 生成电子发票成功，更新数据库，
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            } else {
                log.error("云南非九请求生成电子发票失败");
                consumeStatus = "7";
                t.setStatus(consumeStatus);
                // 生成电子发票失败，更新数据库，
                issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
            }


            // 经过 沟通  等待几秒钟即可 下载发票
            // 调接口  生成发票
            log.info(DateUtils.getCurrentTime() + "云南非九投保单号是 " + tbNo + " 下载发票开始，入参" + info.asXML());
            seqNo = Long.toString(Math.abs(new Random().nextLong()));
            responseEntity = dexClient.text("edu", "20190516036", "1.0", seqNo, info.asXML());

            log.info(DateUtils.getCurrentTime() + "云南非九投保单号是 " + tbNo + " 下载发票结束，回参" + responseEntity.getBody());
            // 请求200，继续执行
            if (responseEntity.getStatusCodeValue() != 200) {
                log.error("云南非九请求下载电子发票失败");
                t.setStatus("6");
                t.setTimes(1);
                issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
            } else {
                ebody = responseEntity.getBody();
                doc = DocumentHelper.parseText(ebody);
                ebodyElement = doc.getRootElement();
                String code = ebodyElement.element("code").getStringValue();
                if ("0000".equals(code)) {
                    String eInvoiceId = ebodyElement.element("data").getStringValue();
                    t.setStatus("2");
                    t.setEInvoiceId(eInvoiceId);
                    bindInvoice(tbNo, eInvoiceId, t);// todo 07-15 11:36
                } else {
                    t.setStatus("6");
                    t.setTimes(1);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
            return true;
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}